package de.lgohlke.compress;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.lgohlke.collection.SavedSpace;
import de.lgohlke.helper.CompressionHelper;
import de.lgohlke.helper.CompressionHelper.TYPE;

/**
 * <p>ByteCompressor class.</p>
 *
 * @author lars
 * @version $Id: $
 */
public class ByteCompressor implements ICompressor<byte[]>
{
  private final static Logger          log  = LoggerFactory.getLogger(ByteCompressor.class);
  private final CompressionHelper.TYPE type = TYPE.GZIP;

  /*
   * (non-Javadoc)
   * @see de.lgohlke.AST.ICompressor#compress(java.lang.Object)
   */
  /**
   * <p>compress.</p>
   *
   * @param value an array of byte.
   * @return a {@link de.lgohlke.compress.CompressableValue} object.
   */
  public CompressableValue<byte[]> compress(final byte[] value)
  {
    CompressableValue<byte[]> result = null;
    if ((value != null))
    {
      try
      {
        byte[] bytesCompressed = CompressionHelper.compress(value).type(type).getBytes();

        if (value.length > bytesCompressed.length)
        {
          result = new CompressableValue<byte[]>(null, true, bytesCompressed);
        }
        else
        {
          result = new CompressableValue<byte[]>(value, false);
        }
      }
      catch (IOException e)
      {
        log.error(e.getMessage(), e);
      }
    }
    else
    {
      result = new CompressableValue<byte[]>(null, false);
    }
    return result;
  }

  /*
   * (non-Javadoc)
   * @see de.lgohlke.AST.ICompressor#decompress(java.lang.Object)
   */
  /** {@inheritDoc} */
  public byte[] decompress(final CompressableValue<byte[]> vo)
  {
    byte[] result = null;
    if (vo.isCompressed())
    {
      try
      {
        result = CompressionHelper.uncompress(vo.getRaw()).type(type).getBytes();
      }
      catch (IOException e)
      {
        log.error(e.getMessage(), e);
      }
    }
    else
    {
      result = vo.getValue();
    }
    return result;
  }

  /*
   * (non-Javadoc)
   * @see de.lgohlke.AST.ICompressor#savedSpace(java.lang.Object)
   */
  /** {@inheritDoc} */
  public SavedSpace savedSpace(final CompressableValue<byte[]> vo)
  {
    SavedSpace savedSpace = new SavedSpace();

    if (vo.isCompressed() && (vo.getRaw() != null))
    {
      int compressed = vo.getRaw().length;
      int raw = decompress(vo).length;

      savedSpace.setRawSize(raw);
      savedSpace.setSavedSize(raw - compressed);
    }

    return savedSpace;
  }
}
